package com.ktg.mes.unit.sql.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ktg.mes.pro.domain.ProTask;
import com.ktg.mes.unit.other.SQLListenerModel;
import com.ktg.mes.unit.other.SQLListener;
import com.ktg.mes.unit.sql.domain.*;
import com.ktg.mes.unit.sql.mapper.SQLToolMapper;
import com.ktg.mes.unit.sql.service.SQLToolService;
import com.ktg.mes.wm.domain.WmStockWillOut;
import com.ktg.mes.wm.service.impl.WmItemRecptLineServiceImpl;
import com.ktg.mes.wm.service.impl.WmMaterialStockServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Service
public class SQLToolServiceImpl extends ServiceImpl<SQLToolMapper, SQLToolModel> implements SQLToolService {

    // spring注入ApplicationContext
    @Autowired
    private ApplicationContext context;

    /***
     *动态初始化Service
     * @return
     */
    @SuppressWarnings("unchecked")
    public  IService getService(Class clazz) {
        try {
            // 逻辑处理你需要实例化的类
            String beanName =  clazz.getSimpleName();
            String firstLowerBeanName = beanName.substring(0,1).toLowerCase()+beanName.substring(1,beanName.length());
            Object obj = context.getBean(firstLowerBeanName, clazz);
            if (obj instanceof IService ){
                if (obj instanceof ServiceImpl){
                    return  (IService)obj;
                }else {
                    throw new RuntimeException(" className 需要继承 com.baomidou.mybatisplus.core.mapper.BaseMapper");
                }
            }else {
                throw new RuntimeException(" className 需要继承 com.baomidou.mybatisplus.extension.service.IService");
            }
        } catch (Exception e) {
            System.out.println("请传入正确的 className");
            log.error("同步：updateSql",e);
        }
        return null;
    }

    @Override
    public List<JSONObject> selectSqlMap(String selectSglString) {
        try {
            return getBaseMapper().selectSqlMap(selectSglString);
        }catch (Exception e){
            log.error("同步：updateSql",e);
        }
        return null;
    }

    @Override
    public void updateSql(String updateSglString) {
        try {
            getBaseMapper().updateSql(updateSglString);
        }catch (Exception e){
            log.error("同步：updateSql",e);
        }
    }

    @Override
    public void insertSql(String insertSglString) {
        try {
            getBaseMapper().insertSql(insertSglString);
        }catch (Exception e){
            log.error("同步：updateSql",e);
        }
    }

    @Override
    public void insertModel(SQLToolModel sqlModel){
        try {
            getBaseMapper().insertModel(sqlModel);
        }catch (Exception e){
            log.error("同步：updateSql",e);
        }
    };

    @Override
    public void updateModel(SQLToolModel sqlModel){
        try {
            getBaseMapper().updateModel(sqlModel);
        }catch (Exception e){
            log.error("同步：updateSql",e);
        }
    };

    public List<JSONObject> selectSqlModel(SQLToolModel sqlModel){
        try {
           return getBaseMapper().selectSqlModel(sqlModel);
        }catch (Exception e){
            log.error("同步：updateSql",e);
        }
        return null;
    };

    @Override
    public int updateSortModel(SQLSortModel sqlModel) {
        return getBaseMapper().updateSortModel(sqlModel);
    }




    public boolean dealRelation(List<SQLListenerModel> list, JSONObject oldObj, SQLToolModel sqlToolModel){
        if (list != null && list.size() > 0){
            for (int i = 0; i < list.size(); i++) {
                SQLListenerModel model = list.get(i);
                IService service = getService(model.getClassName());
                boolean flag = false;
                try {
                    flag = (boolean) model.getMethod().invoke(service,oldObj,sqlToolModel);
                } catch (Exception e) {
                    log.error("  "+model.getClassName()+" 提供 ListenerInterface 注解的方法 "+model.getMethod().toString()+" 必须支持 return 返回和 第一位 JSONObject,第二位SQLToolModel 参数",e);
                }
                if (flag == false){
                    try {
                        //先返回回滚
                        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();;
                    }catch (Exception e){

                    }
                    return false;
                }
            }
        }
        return true;
    }


    /**
     * 根据数据和表获取 字段类型
     * @param config
     * @param tableName
     * @return
     */
    public Map<String,MTableColumn> getColumType(SQLDBConfig config, String tableName){

        SQLToolModel columnModel = new SQLToolModel(config,tableName);

        List<MTableColumn> mapList = getBaseMapper().findTableColumn(columnModel);
        HashMap<String,MTableColumn> tableColumns = new HashMap<>();
        for (int i = 0; i < mapList.size(); i++) {
            MTableColumn map = mapList.get(i);
            tableColumns.put(map.getColumn(),map);
        }
        return tableColumns;
    }
    public boolean save(Object object, Class iServiceImpl_Name){
        if (object == null){
            return false;
        }
        IService one = (IService) getService(iServiceImpl_Name);
        if (one != null){
            return one.save(object);
        }
        return false;
    }

    private static Map<String,Map<String, MTableColumn>> tableToColumn = new HashMap<>();
    private static Map<String,MTable> tableInfoMap = new HashMap<>();

    /**
     * 更新表和字段，更新关联Impl
     */
    public synchronized boolean updateAllTableColumn(){
        //获取所有的表和表对应的字段
        List<MTable> mTableList = getBaseMapper().selectAllTable();
        if (mTableList != null && mTableList.size() > 0){
            Map<String,Map<String, MTableColumn>> tableToC = new HashMap<>();
            Map<String,MTable> tableInfo = new HashMap<>();

            for (MTable item:mTableList) {
                Map<String, MTableColumn> mTableColumnMap = getColumType(SQLDBConfig.master,item.getTable());
                tableToC.put(item.getTable(),mTableColumnMap);
                tableInfo.put(item.getTable(),item);
            }
            tableToColumn = tableToC;
            tableInfoMap = tableInfo;
        }
        return true;
    }

    /**
     * 获取表的字段信息
     * @param table
     * @return
     */
    public Map<String, MTableColumn> columnFrom(String table){
        Map<String, MTableColumn> map = tableToColumn.get(table);
        if (map == null){
            updateAllTableColumn();
        }
        map = tableToColumn.get(table);
        return map;
    }


    /**
     * 获取表的信息
     * @param table
     * @return
     */
    public MTable tableFrom(String table){
        MTable map = tableInfoMap.get(table);
        if (map == null){
            updateAllTableColumn();
        }
        map = tableInfoMap.get(table);
        return map;
    }

}
